export function createElement(ele, props, ...children) {
  // 创建 虚拟DOM 对象
  const virtualDOM = {
    $$typeof: Symbol('react.element'),
    ref: null,
    key: null,
    // 标签名 或 组件
    type: '',
    props: {}
  }

  virtualDOM.type = ele

  // virtualDOM.props 必须是一个对象, 而 props 可以为 null
  if (props !== null) {
    virtualDOM.props = {
      ...props
    }
  }

  // children 如果只有一个，那么可以直接给 props.children 赋值，而如果 大于1 ,那么给一个数组(children 本身)
  if (children.length === 1) {
    virtualDOM.props.children = children[0]
  }
  if (children.length > 1) {
    virtualDOM.props.children = children
  }

  return virtualDOM
}


function each(obj, callback) {
  if (obj === null || typeof obj !== 'object') throw new TypeError('对象参数类型错误')
  if (typeof callback !== 'function') throw new TypeError('回调函数类型错误')

  const arr = Reflect.ownKeys(obj)
  arr.forEach(key => {
    let value = obj[key]
    callback(value, key)
  })
}



export function render(virtualDOM, container) {
  const { props, type, } = virtualDOM

  // 标签
  if (typeof type === 'string') {
    // 创建一个元素标签
    const ele = document.createElement(type)

    // 处理props 内容
    each(props, (value, key) => {
      // 处理className
      if (key === 'className') {
        ele.className = value
        return
      }

      // 处理 style
      if (key === 'style') {
        each(value, (val, attr) => {
          ele.style[attr] = val
        })
        return
      }

      // 处理 children 子节点
      if (key === 'children') {
        // children 可能为一段字符文本 也可能是一个数组
        let children = Array.isArray(value) ? value : [value]
        children.forEach(child => {
          if (/^(string|number)$/.test(typeof child)) {
            const textNode = document.createTextNode(child)
            ele.appendChild(textNode)
            return
          }
          // 递归处理 child
          render(child, ele)
        })
        return
      }

      ele.setAttribute(key, value)
    })


    // 插入到容器中
    container.appendChild(ele)
  }

  // 函数组件
  if (typeof type === 'function') {
    // 如果是函数，则执行函数，并且将 props 传递给该函数
    const childVD = type(props)
    render(childVD, container)
  }

  // 类组件 -> 构造函数, 基于 new 执行, 创建类的实例，也会把解析出来的 props 传递进去
  if (typeof type === 'object' && type !== null) {
    /*
      + 每一次的类组件的执行都会创建一个单独的实例
      + 把在类组件中的 render 方法执行，把返回的 jsx (virtualDOM) 当做视图进行渲染！
    */
  }
}
